package ru.mipt.testload.util;

import com.sun.xml.xsom.*;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.swing.*;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.MaskFormatter;
import javax.swing.text.NumberFormatter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;
import java.text.ParseException;

/**
 * @author Pavel G. Belevich
 *         Date: 15.06.2010
 *         Time: 23:18:12
 */
public class NodeTableCellEditor extends DefaultCellEditor {

    private JFormattedTextField textField;

    public NodeTableCellEditor() {
        super(new JFormattedTextField());

        final JFormattedTextField textField = (JFormattedTextField) getComponent();
        this.textField = textField;
        this.textField.setFocusLostBehavior(JFormattedTextField.PERSIST);
        textField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "check");
        textField.getActionMap().put("check", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                if (!textField.isEditValid()) {
                    if (userSaysRevert()) {
                        textField.postActionEvent();
                    }
                } else {
                    try {
                        textField.commitEdit();
                        textField.postActionEvent();
                    } catch (java.text.ParseException exc) {
                    }
                }
            }
        });

    }

    protected boolean userSaysRevert() {
        Toolkit.getDefaultToolkit().beep();
        textField.selectAll();
        Object[] options = {"Edit", "Revert"};
        int answer = JOptionPane.showOptionDialog(
                SwingUtilities.getWindowAncestor(textField),
                "Error",
                "Invalid Text Entered",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.ERROR_MESSAGE,
                null,
                options,
                options[1]);

        if (answer == 1) {
            textField.setValue(textField.getValue());
            return true;
        }
        return false;
    }

    public boolean stopCellEditing() {
        if (textField.isEditValid()) {
            try {
                textField.commitEdit();
            } catch (java.text.ParseException exc) {
            }
        } else {
            if (!userSaysRevert()) {
                return false;
            }
        }
        return super.stopCellEditing();
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {

        XsdTreeTable xsdTreeTable = (XsdTreeTable) table;

        XsdTreeTableModel xsdTreeTableModel = xsdTreeTable.getXsdTreeTableModel();

        Node node = (Node) xsdTreeTable.getPathForRow(row).getLastPathComponent();

        short nodeType = node.getNodeType();

        Component component = super.getTableCellEditorComponent(table, value, isSelected, row, column);

        if (Node.ELEMENT_NODE == nodeType) {

            Element element = (Element) node;

            XSElementDecl xsElementDecl = xsdTreeTableModel.getXSElementDeclByElement(element);

            XSType xsType = xsElementDecl.getType();

            configureTableCellEditorComponentForElement(xsdTreeTable, component, xsType, isSelected, row, column);

        } else if (Node.ATTRIBUTE_NODE == nodeType) {

            Attr attr = (Attr) node;

            XSAttributeDecl xsAttributeDecl = xsdTreeTableModel.getXSAttributeDeclByAttr(attr);

            XSType xsType = xsAttributeDecl.getType();

            configureTableCellEditorComponentForElement(xsdTreeTable, component, xsType, isSelected, row, column);

        }

        return component;
    }

    protected void configureTableCellEditorComponentForElement(XsdTreeTable xsdTreeTable, Component component, XSType xsType, boolean isSelected, int row, int column) {

        JFormattedTextField formattedTextField = (JFormattedTextField) component;

        JFormattedTextField.AbstractFormatter formatter = null;

        if (xsType.isSimpleType()) {
            XSSimpleType xsSimpleType = xsType.asSimpleType();


            Integer minLength = null;
            Integer maxLength = null;
            if (xsSimpleType.isRestriction()) {
                XSRestrictionSimpleType xsRestrictionSimpleType = xsSimpleType.asRestriction();
                for (XSFacet xsFacet : xsRestrictionSimpleType.getDeclaredFacets()) {
                    if ("minLength".equals(xsFacet.getName())) {
                        minLength = Integer.valueOf(xsFacet.getValue().value);
                    } else if ("maxLength".equals(xsFacet.getName())) {
                        maxLength = Integer.valueOf(xsFacet.getValue().value);
                    } else {
                        //TODO
                    }
                }
            } else {
                //TODO
            }


            XSSimpleType standardSimpleBaseType = Utils.getStandardSimpleBaseType(xsSimpleType);

            String name = standardSimpleBaseType.getName();
            if ("integer".equals(name)) {
                formatter = new NumberFormatter(NumberFormat.getIntegerInstance());
            } else if ("string".equals(name)) {
                StringFormatter stringFormatter = new StringFormatter();
                stringFormatter.setMinLength(minLength);
                stringFormatter.setMaxLength(maxLength);
                formatter = stringFormatter;
            } else {
                //TODO
            }


        } else if (xsType.isComplexType()) {

        }

        formattedTextField.setFormatterFactory(new DefaultFormatterFactory(formatter));
    }


}
